package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.ExperimentProject;
import com.ruoyi.business.mapper.ExperimentProjectMapper;
import com.ruoyi.business.param.LabCountXmlParam;
import com.ruoyi.business.service.IExperimentProjectService;
import com.ruoyi.business.vo.*;
import com.ruoyi.common.utils.CommentUtil;
import com.ruoyi.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 实验项目管理Service业务层处理
 *
 * @author qiancheng
 * @date 2025-06-13
 */
@Service
public class ExperimentProjectServiceImpl extends ServiceImpl<ExperimentProjectMapper, ExperimentProject> implements IExperimentProjectService
{
    @Autowired
    private ExperimentProjectMapper experimentProjectMapper;

    /**
     * 查询实验项目管理
     *
     * @param id 实验项目管理主键
     * @return 实验项目管理
     */
    @Override
    public ExperimentProject selectExperimentProjectById(Long id)
    {
        return experimentProjectMapper.selectExperimentProjectById(id);
    }

    /**
     * 查询实验项目管理列表
     *
     * @param experimentProject 实验项目管理
     * @return 实验项目管理
     */
    @Override
    public List<ExperimentProject> selectExperimentProjectList(ExperimentProject experimentProject)
    {
        return experimentProjectMapper.selectExperimentProjectList(experimentProject);
    }

    /**
     * 新增实验项目管理
     *
     * @param experimentProject 实验项目管理
     * @return 结果
     */
    @Override
    public String insertExperimentProject(MultipartFile[] files, ExperimentProject experimentProject) throws IOException, InterruptedException {
        // 获取并处理开始时间，去除前导零
        String startTime = experimentProject.getStartTime();
        if (startTime != null && !startTime.isEmpty()) {
            experimentProject.setStartTime(removeLeadingZeroFromTime(startTime));
        }

        // 获取并处理结束时间，去除前导零
        String endTime = experimentProject.getEndTime();
        if (endTime != null && !endTime.isEmpty()) {
            experimentProject.setEndTime(removeLeadingZeroFromTime(endTime));
        }
        experimentProject.setCreateTime(DateUtils.getNowDate());
        if(files != null && files.length > 0){
            experimentProject.setDraw(CommentUtil.upLoadFiles(files));
        }
        experimentProjectMapper.insert(experimentProject);
        return experimentProject.getDraw();
    }

    /**
     * 去除时间字符串中的小时部分前导零
     * 例如："09:00" -> "9:00"，"08:30" -> "8:30"
     */
    private String removeLeadingZeroFromTime(String time) {
        // 检查时间格式是否正确（简单检查）
        if (time.contains(":")) {
            String[] parts = time.split(":");
            if (parts.length == 2) {
                // 去除小时部分的前导零
                String hour = parts[0].replaceFirst("^0+", "");
                // 如果小时部分全是零，保留一个零
                if (hour.isEmpty()) {
                    hour = "0";
                }
                return hour + ":" + parts[1];
            }
        }
        // 如果格式不正确，返回原始值
        return time;
    }

    /**
     * 修改实验项目管理
     *
     * @param experimentProject 实验项目管理
     * @return 结果
     */
    @Override
    public int updateExperimentProject(ExperimentProject experimentProject)
    {
        experimentProject.setUpdateTime(DateUtils.getNowDate());
        return experimentProjectMapper.updateExperimentProject(experimentProject);
    }

    /**
     * 批量删除实验项目管理
     *
     * @param ids 需要删除的实验项目管理主键
     * @return 结果
     */
    @Override
    public int deleteExperimentProjectByIds(Long[] ids)
    {
        return experimentProjectMapper.deleteExperimentProjectByIds(ids);
    }

    /**
     * 删除实验项目管理信息
     *
     * @param id 实验项目管理主键
     * @return 结果
     */
    @Override
    public int deleteExperimentProjectById(Long id)
    {
        return experimentProjectMapper.deleteExperimentProjectById(id);
    }

    /**
     * 实验平台管理->>实验项目管理->>更多->>根据年月周查询实验次数
     * @param labCountXmlParam
     * @return
     */
    @Override
    public LabCountVo getCountByDate(LabCountXmlParam labCountXmlParam) {
        if (labCountXmlParam.getSelectType()==1) {
            List<LabCountXmlVo> countByDateList = baseMapper.getCountByDate(labCountXmlParam);
            if (countByDateList.size()>0) {
                List<String> dayList = countByDateList.stream().map(LabCountXmlVo::getOfDay).collect(Collectors.toList());
                List<Integer> countList = countByDateList.stream().map(LabCountXmlVo::getDayCount).collect(Collectors.toList());
                return new LabCountVo(dayList,countList);
            }
        }
        List<LabCountXmlVo> countByWeekList = baseMapper.getCountByWeek(labCountXmlParam);
        if (countByWeekList.size()>0) {
            List<String> dayList = countByWeekList.stream().map(LabCountXmlVo::getOfDay).collect(Collectors.toList());
            List<Integer> countList = countByWeekList.stream().map(LabCountXmlVo::getDayCount).collect(Collectors.toList());
            return new LabCountVo(dayList,countList);
        }
        return null;
    }

    /**
     * 实验平台管理->>实验项目管理->>更多->>根据年月周查询实验项目列表
     * @param labCountXmlParam
     * @return
     */
    @Override
    public List<ExperimentProject> getListByDate(LabCountXmlParam labCountXmlParam) {
        if (labCountXmlParam.getSelectType()==1) {
            return experimentProjectMapper.selectExperimentProjectList(new ExperimentProject(labCountXmlParam));
        }
        return baseMapper.selectExProjectListByWeek(labCountXmlParam);
    }

    /**
     * 实验平台管理->>实验项目管理->>更多->>导出数据->>导出年月周查询实验项目管理列表
     * @param labCountXmlParam
     * @return
     */
    @Override
    public List<ExperimentProjectExportVo> getListByDateExport(LabCountXmlParam labCountXmlParam) {
        if (labCountXmlParam.getSelectType()==1) {
            return experimentProjectMapper.ExportExperimentProjectList(new ExperimentProject(labCountXmlParam));
        }
        return baseMapper.ExportExProjectListByWeek(labCountXmlParam);
    }

    /**
     * 首页->>实验次数->>根据年月查询实验平台的实验次数
     * @param experimentProject
     * @return
     */
    @Override
    public List<LabInfoVo> getCountByLab(ExperimentProject experimentProject) {
        return baseMapper.getCountByLab(experimentProject);
    }

    /**
     * 根据实验平台ID获取实验项目列表
     *
     * @param experimentProject 实验平台
     * @return 实验项目集合
     */
    @Override
    public List<ExperimentProject> selectProjectsByLabId(ExperimentProject experimentProject) {
        return experimentProjectMapper.selectProjectsByLabId(experimentProject);
    }

    /**
     * 获取所有实验时间列表
     */
    @Override
    public List<String> getExperimentTimeList(String rackId) {
        List<ExperimentProject> list = this.list(new QueryWrapper<ExperimentProject>()
                .eq("rack_id", rackId)
                .select("experiment_time")
                .orderByAsc("experiment_time"));
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        return list.stream()
                .map(ExperimentProject::getExperimentTime)
                .map(sdf::format)   // 转成 yyyy-MM-dd 字符串
                .distinct()         // 去重
                .collect(Collectors.toList());
    }

    /**
     * 根据实验日期查询当天实验的时间范围列表
     */
    @Override
    public List<ExperimentTimeRangeVO> getExperimentTimeRangesByDate(Date experimentDate, String rackId) {
        QueryWrapper<ExperimentProject> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("rack_id", rackId)  // 精确匹配日期
                .eq("experiment_time", experimentDate)  // 精确匹配日期
                .orderByAsc("start_time");

        List<ExperimentProject> list = this.list(queryWrapper);

        // 用 startTime+endTime 作为唯一键去重
        return list.stream()
                // 过滤掉 startTime 或 endTime 为 null 的记录
                .filter(ep -> ep.getStartTime() != null && ep.getEndTime() != null)
                .map(ep -> {
                    ExperimentTimeRangeVO vo = new ExperimentTimeRangeVO();
                    vo.setImportDay(ep.getExperimentTime());
                    vo.setStartTime(ep.getStartTime());
                    vo.setEndTime(ep.getEndTime());
                    return vo;
                })
                // 去重 + 排序
                .collect(Collectors.collectingAndThen(
                        Collectors.toMap(
                                vo -> vo.getStartTime() + "-" + vo.getEndTime(), // 去重 key
                                vo -> vo,
                                (existing, replacement) -> existing
                        ),
                        map -> map.values().stream()
                                .sorted(Comparator.comparing(ExperimentTimeRangeVO::getStartTime))
                                .collect(Collectors.toList())
                ));
    }
}
